package test.json;

import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.cfg.MapperConfig;
import com.fasterxml.jackson.databind.introspect.AnnotatedField;
import com.fasterxml.jackson.databind.introspect.AnnotatedMember;
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod;
import com.fasterxml.jackson.databind.introspect.AnnotatedParameter;

public class CustomPropertyNamingStrategy extends PropertyNamingStrategy {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private final Map<Class<?>, Map<String, String>> mapper = new HashMap<Class<?>, Map<String, String>>();

	/**
	 * 注册映射关系
	 * 
	 * @param clazz
	 * @param nameMapper
	 */
	public void regist(Class<?> clazz, Map<String, String> nameMapper) {
		if (clazz == null || nameMapper == null) {
			throw new NullPointerException();
		}

		mapper.put(clazz, nameMapper);
	}

	@Override
	public String nameForField(MapperConfig<?> config, AnnotatedField field,
			String defaultName) {
		return translate(field, defaultName);
	}

	@Override
	public String nameForGetterMethod(MapperConfig<?> config,
			AnnotatedMethod method, String defaultName) {
		return translate(method, defaultName);
	}

	@Override
	public String nameForSetterMethod(MapperConfig<?> config,
			AnnotatedMethod method, String defaultName) {
		return translate(method, defaultName);
	}

	@Override
	public String nameForConstructorParameter(MapperConfig<?> config,
			AnnotatedParameter ctorParam, String defaultName) {
		return translate(ctorParam, defaultName);
	}

	private String translate(AnnotatedMember member, String propertyName) {
		Map<String, String> nameMapper = mapper.get(member.getDeclaringClass());
		if (nameMapper == null || nameMapper.isEmpty()) {
			return propertyName;
		}
		
		String assignedName = nameMapper.get(propertyName);
		if (assignedName == null) {
			return propertyName;
		} 
		return assignedName;
		
	}

}
